package cool.mor.service.impl;

import cool.mor.dao.EmployeeRepository;
import cool.mor.dao.UserRepository;
import cool.mor.dto.RegisterDto;
import cool.mor.dto.TestDto;
import cool.mor.dto.UserDto;
import cool.mor.entity.Employee;
import cool.mor.entity.User;
import cool.mor.form.RegisterForm;
import cool.mor.form.TestForm;
import cool.mor.form.UserForm;
import cool.mor.service.LoginService;
import cool.mor.utils.UUIDGenerator;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    UserRepository userRepository;
    @Autowired
    EmployeeRepository employeeRepository;

    @Override
    public UserDto login(UserForm userForm) {
        /**
         * 在此接收的是一个登录的用户数据：user password
         * 需要做的是
         *          1、将userForm 转换为User
         *          2、将User与数据库中对比   -----交给 shiro 做
         *              a、成功的情况 ---返回一个状态码和消息，以及token
         *              b、失败的情况  ---返回一个状态码和消息，没有token
         *                  如何获得token
         *          3、封装成一个userDto
         */
        User user = new User();
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(userForm,user);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getPhoneNumber(), user.getPassword());
        try {
            /**
             * 将加密好的token传入到当前用户 “subject” 对象中,执行成功login方法后，相当于在shiro中注册了此对象，用于后续能够成功通过拦截器
             */
            subject.login(token);
            userDto.setToken(token.toString());
            /**
             * 将employeeId传到前端
             */
            userDto.setEmployeeId(userRepository.findByPhoneNumber(user.getPhoneNumber()).getId());
            userDto.setCode("200");
            userDto.setMessage("登录成功");
            return userDto;
        }catch (UnknownAccountException e){
            userDto.setCode("401");
            userDto.setMessage("账号不存在");
            return userDto;
        }catch (IncorrectCredentialsException e){
            userDto.setCode("401");
            userDto.setMessage("密码错误");
            return userDto;
        }

    }

    @Override
    public TestDto test(TestForm testForm) {
        /**
         *
         */
        return null;
    }

    @Override
    public RegisterDto register(RegisterForm registerForm) {
        User user = new User();
        RegisterDto registerDto = new RegisterDto();
        user.setPhoneNumber(registerForm.getRegisterPhoneNumber());
        user.setPassword(registerForm.getRegisterPassword());
        /**
         *    1、将传入的手机号与数据库的中已经存在的手机号对比，若存在，则注册不成功：账号已经注册过      若不存在，则注册成功并插入数据库，提示：账号注册成功
         *    2、若生成的uuid主键已经存在，                返回如上信息                               若不存在，则注册成功并插入数据库，提示：成功
         */
        if(!userRepository.existsByPhoneNumber(user.getPhoneNumber())){
            /**
             * 代表手机号不存在，可以进行插入操作
             */
            String uuid = UUIDGenerator.getUUID();
            /**
             * 若uuid重复，则重新获取
             */
            while (userRepository.existsById(uuid)){
                uuid = UUIDGenerator.getUUID();
            }
            user.setId(uuid);
            userRepository.save(user);
            /**
             * 注册成功之后需要关联 对应的employee表和部门表
             *             employee.setDeptNo("1")    物理数据库设计了外键，需要给一个默认部门
             */
            Employee employee = new Employee();
            employee.setId(uuid);
            employee.setDeptNo("1");

            employeeRepository.save(employee);
            registerDto.setCode("200");
            registerDto.setMessage("注册成功");
            return registerDto;
        }
        registerDto.setCode("401");
        registerDto.setMessage("该号码已经注册，请换个号码再试");
        return registerDto;
    }
}
